package com.hm.ipay.service.impl;

import com.hm.ipay.dao.AccountConversionPlanMapper;
import com.hm.ipay.dao.AccountTransactionRecordMapper;
import com.hm.ipay.dao.GlobalConfigMapper;
import com.hm.ipay.dao.UserAccountMapper;
import com.hm.ipay.domain.result.ExceptionMsg;
import com.hm.ipay.domain.result.ResponseData;
import com.hm.ipay.entity.AccountConversionPlan;
import com.hm.ipay.entity.AccountTransactionRecord;
import com.hm.ipay.entity.GlobalConfig;
import com.hm.ipay.entity.UserAccount;
import com.hm.ipay.service.TransferService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.List;

@Service
public class TransferServiceImpl implements TransferService {

    private final static BigDecimal _TEN = BigDecimal.TEN;
    private final static BigDecimal _HUNDRED = BigDecimal.TEN.multiply(BigDecimal.TEN);

    @Autowired
    UserAccountMapper userAccountMapper;

    @Autowired
    AccountTransactionRecordMapper accountTransactionRecordMapper;

    @Autowired
    GlobalConfigMapper globalConfigMapper;

    @Autowired
    AccountConversionPlanMapper planMapper;

    @Override
    public ResponseData transfer(Long id, Long targetId, BigDecimal amount) {
//        System.out.println(id);
//        System.out.println(targetId);
//        System.out.println(amount);
        if (id == null || targetId == null || amount == null) {
            return new ResponseData(ExceptionMsg.ParameterError);
        }
        UserAccount mine = userAccountMapper.selectByPrimaryKey(id);
        if (mine.getActivateStatus() != 0) {
            return new ResponseData(ExceptionMsg.AccountStatusError);
        }
        BigDecimal minePreTA = mine.getBalance();  // 我的账户转账前金额
        if (mine.getBalance().compareTo(amount) < 0) {
            return new ResponseData(ExceptionMsg.BalanceNotEnough);
        } else {
            mine.setBalance(mine.getBalance().subtract(amount));
        }
        BigDecimal minePostTA = mine.getBalance();  // 我的账户转账后金额
        UserAccount target = userAccountMapper.selectByPrimaryKey(targetId);
        if (target.getActivateStatus() != 0) {
            return new ResponseData(ExceptionMsg.TargetAccountStatusError);
        }
        BigDecimal targetPreTA = target.getBalance(); // 目标账户转账前金额
        target.setBalance(target.getBalance().add(amount));
        BigDecimal targetPostTA = target.getBalance(); // 目标账户转账后金额
        userAccountMapper.updateByPrimaryKeySelective(mine);
        userAccountMapper.updateByPrimaryKeySelective(target);
        // 记录流水
        AccountTransactionRecord mineRecord = new AccountTransactionRecord();
        AccountTransactionRecord targetRecord = new AccountTransactionRecord();

        mineRecord.setUserId(mine.getId());
        mineRecord.setUserName(mine.getUserName());
        mineRecord.setTransactionType(0);
        mineRecord.setTransactionAmount(amount);
        mineRecord.setTradeDirection((byte)1);
        mineRecord.setPreTransactionAmount(minePreTA);
        mineRecord.setPostTransactionAmount(minePostTA);
        mineRecord.setFrozenStatus((byte)0);

        targetRecord.setUserId(target.getId());
        targetRecord.setUserName(target.getUserName());
        targetRecord.setTransactionType(0);
        targetRecord.setTransactionAmount(amount);
        targetRecord.setTradeDirection((byte)0);
        targetRecord.setPreTransactionAmount(targetPreTA);
        targetRecord.setPostTransactionAmount(targetPostTA);
        targetRecord.setFrozenStatus((byte)0);

        accountTransactionRecordMapper.insertSelective(mineRecord);
        accountTransactionRecordMapper.insertSelective(targetRecord);
        return new ResponseData(ExceptionMsg.SUCCESS, mine);
    }

    @Override
    public ResponseData switchToCredit(Long id, BigDecimal amount) {
        if (id == null || amount == null) {
            return new ResponseData(ExceptionMsg.ParameterError);
        }
        GlobalConfig config = globalConfigMapper.selectByPrimaryKey(1L);
        BigDecimal amountIn = amount.multiply(BigDecimal.valueOf((double)config.getInProportion() / 100));
        UserAccount mine = userAccountMapper.selectByPrimaryKey(id);
        if (mine.getActivateStatus() != 0) {
            return new ResponseData(ExceptionMsg.AccountStatusError);
        }
        BigDecimal minePreTA = mine.getBalance();
        if (mine.getBalance().compareTo(amount) < 0) {
            return new ResponseData(ExceptionMsg.BalanceNotEnough);
        } else {
            mine.setBalance(mine.getBalance().subtract(amount));
            mine.setCreditBalance(mine.getCreditBalance().add(amountIn));
        }
        BigDecimal minePostTA = mine.getBalance();
        userAccountMapper.updateByPrimaryKeySelective(mine);

        /* 流水记录 */
        AccountTransactionRecord mineRecord = new AccountTransactionRecord();
        mineRecord.setUserId(mine.getId());
        mineRecord.setUserName(mine.getUserName());
        mineRecord.setTransactionType(1);
        mineRecord.setTransactionAmount(amountIn);
        mineRecord.setTradeDirection((byte)1);
        mineRecord.setPreTransactionAmount(minePreTA);
        mineRecord.setPostTransactionAmount(minePostTA);
        mineRecord.setFrozenStatus((byte)0);
        accountTransactionRecordMapper.insertSelective(mineRecord);

        /* 转换计划 */
        AccountConversionPlan plan = new AccountConversionPlan();
        plan.setUserId(mine.getId());
        plan.setBaseAmount(amountIn);
        plan.setBalance(amountIn);
        plan.setOutProportion(config.getOutProportion());
        plan.setStatus((byte)0);
        planMapper.insertSelective(plan);

        return new ResponseData(ExceptionMsg.SUCCESS, mine);
    }

    @Override
    public void autoSwitchBack() {
        GlobalConfig config = globalConfigMapper.selectByPrimaryKey(1L);
        //List<UserAccount> list = userAccountMapper.selectCreditAccount();
        List<AccountConversionPlan> planList = planMapper.selectAllPlanByStatus(0);
        AccountTransactionRecord mineRecord = null;
        UserAccount mine = null;
        AccountConversionPlan plan = null;
        for (int i = 0; i < planList.size(); i++) {
            plan = planList.get(i);
            Long userId = plan.getUserId();
            mine = userAccountMapper.selectByPrimaryKey(userId);
            BigDecimal minePreTA = mine.getBalance();
            // 对比计划中的转换比例与配置表中的比例
            int outProportion = config.getOutProportion();
            int planOutProportion = plan.getOutProportion();
            if (outProportion != planOutProportion) {
                planOutProportion = outProportion;
                plan.setOutProportion(outProportion);
                plan.setBaseAmount(plan.getBalance());
            }
            BigDecimal amountOut = plan.getBaseAmount().multiply(BigDecimal.valueOf((double)planOutProportion / 100));
            mine.setBalance(mine.getBalance().add(amountOut));
            if (mine.getCreditBalance().subtract(amountOut).compareTo(BigDecimal.ZERO) <= 0) {
                mine.setCreditBalance(BigDecimal.ZERO);
            } else {
                mine.setCreditBalance(mine.getCreditBalance().subtract(amountOut));
            }
            if (plan.getBalance().subtract(amountOut).compareTo(BigDecimal.ZERO) <= 0) {
                plan.setBalance(BigDecimal.ZERO);
                plan.setStatus((byte)3);
            } else {
                plan.setBalance(plan.getBalance().subtract(amountOut));
            }
            BigDecimal minePostTA = mine.getBalance();
            System.out.println("转换金额=" + amountOut);
            planMapper.updateByPrimaryKeySelective(plan);
            userAccountMapper.updateByPrimaryKeySelective(mine);
            /* 流水记录 */
            mineRecord = new AccountTransactionRecord();
            mineRecord.setUserId(mine.getId());
            mineRecord.setUserName(mine.getUserName());
            mineRecord.setTransactionType(1);
            mineRecord.setTransactionAmount(amountOut);
            mineRecord.setTradeDirection((byte)0);
            mineRecord.setPreTransactionAmount(minePreTA);
            mineRecord.setPostTransactionAmount(minePostTA);
            mineRecord.setFrozenStatus((byte)0);
            accountTransactionRecordMapper.insertSelective(mineRecord);
            // 分润逻辑  二级受益人 拿10% 一级受益人拿1%
            // 二级受益人
            int benefitRatio = config.getBenefitRatio();
            UserAccount invitor_lv2 = userAccountMapper.selectByPrimaryKey(mine.getSecondaryBeneficiary());
            if (invitor_lv2 != null) {
                BigDecimal lv2PreTA = invitor_lv2.getBalance();
                //BigDecimal lv2AmountOut = invitor_lv2.getBalance().add(amountOut.divide(_TEN, RoundingMode.HALF_EVEN));
                BigDecimal lv2AmountOut = amountOut.multiply(BigDecimal.valueOf((double)benefitRatio / 100));
                invitor_lv2.setBalance(invitor_lv2.getBalance().add(lv2AmountOut));
                BigDecimal lv2PostTA = invitor_lv2.getBalance();
                System.out.println("l2转换金额=" + lv2AmountOut);
                userAccountMapper.updateByPrimaryKeySelective(invitor_lv2);
                AccountTransactionRecord lv2Record = new AccountTransactionRecord();
                lv2Record.setUserId(invitor_lv2.getId());
                lv2Record.setUserName(invitor_lv2.getUserName());
                lv2Record.setTransactionType(2);
                lv2Record.setTransactionAmount(lv2AmountOut);
                lv2Record.setTradeDirection((byte)0);
                lv2Record.setPreTransactionAmount(lv2PreTA);
                lv2Record.setPostTransactionAmount(lv2PostTA);
                lv2Record.setFrozenStatus((byte)0);
                lv2Record.setTransactionOpposite(mine.getId());
                accountTransactionRecordMapper.insertSelective(lv2Record);
                // 一级受益人
                UserAccount invitor_lv1 = userAccountMapper.selectByPrimaryKey(mine.getPrimaryBeneficiary());
                if (invitor_lv1 != null) {
                    BigDecimal lv1PreTA = invitor_lv1.getBalance();
                    BigDecimal lv1AmountOut = lv2AmountOut.multiply(BigDecimal.valueOf((double)benefitRatio / 100));
                    invitor_lv1.setBalance(invitor_lv1.getBalance().add(lv1AmountOut));
                    BigDecimal lv1PostTA = invitor_lv1.getBalance();
                    System.out.println("l1转换金额=" + lv1AmountOut);
                    userAccountMapper.updateByPrimaryKeySelective(invitor_lv1);
                    AccountTransactionRecord lv1Record = new AccountTransactionRecord();
                    lv1Record.setUserId(invitor_lv1.getId());
                    lv1Record.setUserName(invitor_lv1.getUserName());
                    lv1Record.setTransactionType(2);
                    lv1Record.setTransactionAmount(lv1AmountOut);
                    lv1Record.setTradeDirection((byte)0);
                    lv1Record.setPreTransactionAmount(lv1PreTA);
                    lv1Record.setPostTransactionAmount(lv1PostTA);
                    lv1Record.setFrozenStatus((byte)0);
                    lv1Record.setTransactionOpposite(mine.getId());
                    accountTransactionRecordMapper.insertSelective(lv1Record);
                }
            }
        }
    }
}
